const std = @import("std");
const uart = @import("uart.zig");
const page = @import("page.zig");
const task = @import("task.zig");
const trap = @import("trap.zig");

pub const print = uart.print;
pub const allocator = page.fba.allocator();

pub fn panic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
    @branchHint(.cold);
    print("KERNEL PANIC: {s}\n", .{msg});
    while (true) {}
}

const STACK_SIZE = 1024 * 16;
export var stack0: [STACK_SIZE]u8 align(16) = undefined;

const start_code = std.fmt.comptimePrint(
    \\  csrr    t0, mhartid
    \\  beqz    t0, hart_0
    \\
    \\park:
    \\  wfi
    \\  j       park
    \\
    \\hart_0:
    \\  # Setup stacks, the stack grows from bottom to top, so we put the
    \\  # stack pointer to the very end of the stack range.
    \\  la      sp, stack0 + {}     # set the initial stack pointer
    \\                              # to the end of the first stack space
    \\  j       kmain               # hart 0 jump to kmain function
, .{STACK_SIZE});

export fn _start() linksection(".os_start") callconv(.naked) noreturn {
    asm volatile (start_code);
}

export fn kmain() noreturn {
    uart.init();
    page.init();
    task.init();
    trap.init();

    main() catch |e| @panic(@errorName(e));

    while (true) {} // stop here!
}

fn main() !void {
    print("Hello, RVOS!\n", .{});

    page.info();
    task.info();

    task.schedule();

    print("Would not go here!\n", .{}); // 加上这句话，在 debug 和 fast 模式下会变得很慢??
    //unreachable; // 再加上这句话就不会了
    // 而且禁用 c 扩展也不会
    // 或者 user_task0() 里不调用 trap.tests() 也不会
    // 或者 task.schedule() 放在 task.tasks.schedule() 也不会
    // 搞不懂为啥
}
